import mitt, { Handler } from 'mitt'
import { FlowchartJSON, ChartMeta } from './flowchart/models'
const emitter = mitt()
export const events: Array<'new-node-to-canvas' | 'delete-node' | 'node-params-changed' | 'run' | 'download' | 'load'> = []

export const emitNewNode = (nodeType: string): void => {
  emitter.emit('new-node-to-canvas', nodeType)
}

export const setCanvasOnNewNodeCallback = (callback: (nodeType: string) => void): void => {
  emitter.all.set('new-node-to-canvas', [])
  emitter.on('new-node-to-canvas', callback as any)
}

export const emitNodeParamsChanged = (nodeID: string, newParamValues: Record<string, number | string>): void => {
  const newParams: { name: string, value: unknown }[] = []
  for (const name in newParamValues) {
    const v = newParamValues[name]
    if (v != null && v !== "") {
      newParams.push({
        name: name,
        value: v
      })
    }
  }
  emitter.emit('node-params-changed', { nodeID: nodeID, params: newParams })
}

export const addOnNodeParamsChanged = (callback: (newParams: { nodeID: string, params: { name: string, value: unknown }[] }) => void): void => {
  emitter.on('node-params-changed', callback as Handler<unknown>)
}

export const emitRun = (): void => {
  emitter.emit('run')
}

export const setOnRun = (callback: () => void): void => {
  emitter.all.set('run', [])
  emitter.on('run', callback)
}

export const emitDownload = (): void => {
  emitter.emit('download')
}

export const setOnDownload = (callback: () => void): void => {
  emitter.all.set('download', [])
  emitter.on('download', callback)
}

export const emitLoad = (fcJson: FlowchartJSON): void => {
  emitter.emit('load', fcJson)
}

export const setOnLoad = (callback: (fcJson: FlowchartJSON) => void): void => {
  emitter.all.set('load', [])
  emitter.on('load', callback as Handler<unknown>)
}

export const emitShowContextMenuOnNode = (evt: MouseEvent): void => {
  emitter.emit('show-context-menu-on-node', evt)
}

export const setOnShowContextMenuOnNode = (callback: (event: MouseEvent) => void): void => {
  emitter.all.set('show-context-menu-on-node', [])
  emitter.on('show-context-menu-on-node', callback as Handler)
}

export const emitFlipNode = (nodeID: string): void => {
  emitter.emit('flip-node', nodeID)
}

export const setOnNodeFlipped = (callback: (nodeID: string) => void): void => {
  emitter.all.set('flip-node', [])
  emitter.on('flip-node', callback as Handler)
}

export const emitDeleteNode = (nodeID: string): void => {
  emitter.emit('delete-node', nodeID)
}

export const setOnNodeDeleteRequest = (callback: (nodeID: string) => void): void => {
  emitter.all.set('delete-node', [])
  emitter.on('delete-node', callback as Handler)
}

export const emitHighlightPort = (portUUID: string): void => {
  emitter.emit('highlight-port', portUUID)
}

export const setOnHighlightPort = (callback: (portUUID: string) => void) => {
  emitter.all.set('highlight-port', [])
  emitter.on('highlight-port', callback as Handler)
}


export const emitNewPlot = (chartJson: any): void => {
  console.log('emit-new-plot', chartJson)
  emitter.emit('new-chart', chartJson)
}

export const setOnNewChart = (callback: (chartJson: any) => void): void => {
  emitter.all.set('new-chart', [])
  emitter.emit('new-chart', callback as Handler)
}

export const emitEditPortsOnNode = (nodeName: string, direction: "input" | "output") => {
  emitter.emit('edit-ports-on-node', { nodeName, direction })
}


export const setOnEditPortsOnNode = (callback: (nodeName: string, direction: "input" | "output") => void) => {
  emitter.all.set('edit-ports-on-node', [])
  emitter.on('edit-ports-on-node', ((evt: { nodeName: string, direction: "input" | "output" }) => { callback(evt.nodeName, evt.direction) }) as Handler<unknown>)
}

export const emitLoadChartByName = (chartName: string) => {
  emitter.emit('load-chart-by-name', chartName)
}

export const setOnLoadChartByName = (callback: (chartname: string) => void) => {
  emitter.on('load-chart-by-name', callback as Handler)
}